home *** CD-ROM | disk | FTP | other *** search
/ The Best of MacTutor - S…e Code for Volumes 1 to 5 / The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin / Source Code / #46 (Jul 89) / Window Menu Code / Window.p < prev    next >
Text File  |  1989-01-19  |  19KB  |  810 lines

  1. (*******************************************************************
  2.     
  3.     Window.p
  4.     
  5.     Demo of a dynamic Window menu.
  6.     
  7.     (c) 1988, by Clifford Story & Attic Software
  8.     
  9. *******************************************************************)
  10.  
  11. program Window;
  12.     
  13. (******************************************************************)
  14.     
  15.     uses memtypes, quickdraw, osintf, toolintf, packintf, Common;
  16.     
  17. (*******************************************************************
  18.     
  19.     Program constants:
  20.         
  21. *******************************************************************)
  22.  
  23.     const
  24.  
  25.         applenum                =    1001;
  26.             aboutitem        =    1;
  27.             atticitem        =    2;
  28.  
  29.         filenum                =    1002;
  30.             newitem            =    1;
  31.             closeitem        =    2;
  32.             quititem            =    4;
  33.  
  34.         editnum                =    1003;
  35.             undoitem            =    1;
  36.             cutitem            =    3;
  37.             copyitem            =    4;
  38.             pasteitem        =    5;
  39.             clear                =    6;
  40.         
  41.         windnum                =    1004;
  42.             zoomitem            =    1;
  43.         
  44.         messagedialog        =    1001;
  45.         
  46.         windownum            =    1001;
  47.         zoomwindnum            =    1002;
  48.         
  49.         hoffset                =    32;
  50.         voffset                =    20;
  51.         
  52. (*******************************************************************
  53.     
  54.     Program types:
  55.         
  56. *******************************************************************)
  57.     
  58.     type
  59.         
  60.         datarecord            =    record
  61.             dummy                :    WindowRecord;
  62.             recordid            :    integer;
  63.             next                :    integer;
  64.         end;
  65.         datapointer            =    ^datarecord;
  66.     
  67. (*******************************************************************
  68.     
  69.     Program variables:
  70.         
  71. *******************************************************************)
  72.         
  73.     var
  74.     
  75.         APPLEMENU            :    MenuHandle;
  76.         FILEMENU                :    MenuHandle;
  77.         EDITMENU             :    MenuHandle;
  78.         WINDOWMENU             :    MenuHandle;
  79.         
  80.         MENUHEIGHT            :    integer;
  81.         DRAGRECT                :    Rect;
  82.         GROWRECT                :    Rect;
  83.         SCREENRECT            :    Rect;
  84.         
  85.         WINDOWS                :    array [0..17] of datarecord;
  86.         FREE                    :    integer;
  87.         
  88.         OLDROM                :    logical;
  89.         COLUMNS                :    integer;
  90.         ROWS                    :    integer;
  91.         WINDOWCOUNT            :    integer;
  92.         
  93.         DONE                    :    logical;
  94.         JEVENT                :    logical;
  95.         MAINEVENT            :    EventRecord;
  96.         
  97. (******************************************************************)
  98.     
  99.     procedure _datainit; external;
  100.     
  101. (******************************************************************)
  102.     
  103.     {$R-}
  104.     {$SC+}
  105.     
  106. (******************************************************************)
  107.     
  108.     procedure panic;
  109.     
  110.         begin
  111.  
  112.             ExitToShell;
  113.  
  114.         end;
  115.         
  116. (******************************************************************)
  117.         
  118.     procedure centerdialog(thetype : OSType; theid : integer);
  119.         
  120.         var
  121.             thehandle        :    AlertTHndl;
  122.         
  123.         begin
  124.             
  125.             thehandle := AlertTHndl(GetResource(thetype, theid));
  126.             HLock(Handle(thehandle));
  127.             with thehandle^^ do begin
  128.                 
  129.                 with boundsRect do
  130.                     SetRect(boundsRect, 0, 0, right - left, bottom - top);
  131.                 
  132.                 with screenBits.bounds, boundsRect.botright do
  133.                     OffsetRect(boundsRect, (right - left - h) div 2,
  134.                                     (bottom - top - v + 2 * MENUHEIGHT) div 3);
  135.             
  136.             end;
  137.             HUnlock(Handle(thehandle));
  138.         
  139.         end;
  140.     
  141. (******************************************************************)
  142.     
  143.     procedure initmac;
  144.     
  145.         begin
  146.  
  147.             MaxApplZone;
  148.             InitGraf(@thePort);
  149.             InitFonts;
  150.             InitWindows;
  151.             InitCursor;
  152.             InitMenus;
  153.             TEInit;
  154.             InitDialogs(@panic);
  155.             
  156.             UnloadSeg(@_datainit);
  157.             
  158.         end;
  159.         
  160. (******************************************************************)
  161.             
  162.     procedure setupmenus;
  163.             
  164.         begin
  165.         
  166.             APPLEMENU := GetMenu(applenum);
  167.             AddResMenu(APPLEMENU, 'DRVR');
  168.             InsertMenu(APPLEMENU, 0);
  169.             
  170.             FILEMENU := GetMenu(filenum);
  171.             InsertMenu(FILEMENU, 0);
  172.             
  173.             EDITMENU := GetMenu(editnum);
  174.             InsertMenu(EDITMENU, 0);
  175.             
  176.             WINDOWMENU := GetMenu(windnum);
  177.             InsertMenu(WINDOWMENU, 0);
  178.             
  179.             DrawMenuBar;
  180.             
  181.         end;
  182.         
  183. (*******************************************************************
  184.     
  185.     initglobals
  186.     -----------
  187.     
  188.     Initialize all global variables.  This is all standard stuff;
  189.     note, however, that I'm going to keep track of the ROM version,
  190.     since (1) the standard WDEF can't handle zoom windows on the
  191.     64K ROM, so I want to open standard document windows instead;
  192.     and (2) I don't want to enable the “Zoom Front Window” command
  193.     on the 64K ROM.
  194.     
  195. *******************************************************************)
  196.     
  197.     procedure initglobals;
  198.     
  199.         var
  200.             index                :    integer;
  201.     
  202.         begin
  203.  
  204.             for index := 1 to 10 do
  205.                 MoreMasters;
  206.             
  207.             OLDROM := BitTst(Ptr(rom85), 0);
  208.             
  209.             if OLDROM then
  210.                 MENUHEIGHT := 20
  211.             else
  212.                 MENUHEIGHT := shortpointer(mbarheight)^;
  213.     
  214.             if GetResource('PACK', 0) = nil then
  215.                 JEVENT := false
  216.             else
  217.                 JEVENT := (NGetTrapAddress($A860, ToolTrap)
  218.                                 <> NGetTrapAddress($A89F, ToolTrap));
  219.             
  220.             with screenBits.bounds do begin
  221.                 SetRect(DRAGRECT, left + 5, top + MENUHEIGHT + 5,
  222.                                 right - 5, bottom - 25);
  223.                 SetRect(GROWRECT, 160, 100, right - left - 10,
  224.                                 bottom - top - MENUHEIGHT - 10);
  225.                 SetRect(SCREENRECT, left + 5, top + MENUHEIGHT + 25,
  226.                                 right - 5, bottom - 5);
  227.                 COLUMNS := 1 + ((right - left - 330) div hoffset);
  228.                 ROWS := 1 + ((bottom - top - MENUHEIGHT - 230) div voffset);
  229.             end;
  230.             
  231.             for index := 0 to 17 do
  232.                 with WINDOWS[index] do begin
  233.                     recordid := index;
  234.                     next := index + 1;
  235.                 end;
  236.             WINDOWS[17].next := -1;
  237.             
  238.             FREE := 0;
  239.             WINDOWCOUNT := 0;
  240.             
  241.             DONE := false;
  242.             
  243.         end;
  244.  
  245. (*******************************************************************
  246.     
  247.     clickapplemenu
  248.     --------------
  249.     
  250.     This may not be new to you but it is to me!  Instead of using an
  251.     alert for the “About...” box, I'm using a picture.  First I open
  252.     a new GrafPort, then draw the picture in its center.  Note that
  253.     I must re-draw the windows after the user dismisses the screen,
  254.     using PaintBehind.
  255.         
  256. *******************************************************************)
  257.     
  258.     procedure clickapplemenu(theitem : integer);
  259.     
  260.         var
  261.             itemname            :    Str255;
  262.             savedport        :    GrafPtr;
  263.             dummy                :    integer;
  264.             newport            :    GrafPort;
  265.             thepicture        :    PicHandle;
  266.             therect            :    Rect;
  267.  
  268.         begin
  269.         
  270.             if theitem > 3 then begin
  271.                 GetItem(APPLEMENU, theitem, itemname);
  272.                 GetPort(savedport);
  273.                 dummy := OpenDeskAcc(itemname);
  274.                 SetPort(savedport);
  275.             end else if theitem < 3 then begin
  276.                 
  277.                 InitCursor;
  278.                 GetPort(savedport);
  279.                 OpenPort(@newport);
  280.                 SetPort(@newport);
  281.                 
  282.                 thepicture := PicHandle(GetResource('PICT',
  283.                                 1000 + theitem));
  284.                 with thepicture^^.picFrame do
  285.                     SetRect(therect, 0, 0, right - left, bottom - top);
  286.                 with screenBits.bounds, therect.botright do
  287.                     OffsetRect(therect, (right - left - h) div 2,
  288.                                     (bottom - top - v) div 3);
  289.                 DrawPicture(thepicture, therect);
  290.                 
  291.                 repeat until Button;
  292.                 
  293.                 ClosePort(@newport);
  294.                 EnableItem(EDITMENU, 0);
  295.                 DrawMenuBar;
  296.                 PaintBehind(WindowPeek(FrontWindow),
  297.                                 RgnHandle(longpointer(grayrgn)^));
  298.                 
  299.                 SetPort(savedport);
  300.                 FlushEvents(everyEvent, 0);
  301.             
  302.             end;
  303.             
  304.         end;
  305.         
  306. (******************************************************************)
  307.  
  308.     procedure placewindow(thewindow : WindowPtr);
  309.     
  310.         var
  311.             left                :    integer;
  312.             top                :    integer;
  313.     
  314.         begin
  315.             
  316.             left := 5 + hoffset * (WINDOWCOUNT mod COLUMNS);
  317.             top := 5 + MENUHEIGHT
  318.                             + voffset * (1 + (WINDOWCOUNT mod ROWS));
  319.             
  320.             MoveWindow(thewindow, left, top, true);
  321.             
  322.         end;
  323.         
  324. (*******************************************************************
  325.     
  326.     donew
  327.     -----
  328.     
  329.     This routine creates a new window, choosing the window resource
  330.     according to the ROM version.  The refcon is set to zero, to
  331.     indicate that the window is unzoomed.  The new window will be
  332.     automatically added to the Window menu but the size of the menu
  333.     rectangle must be recalculated.
  334.     
  335.     Since the Window menu can't scroll, it can show only 18 windows
  336.     (20 items, minus the zoom command and the dividing line).  So I
  337.     limit the program to those 18.  Since the program is limited to
  338.     18 windows, I allocate a global array of extended WindowRecords
  339.     called WINDOW to avoid fragmenting the heap.  Each WindowRecord
  340.     is extended to include two integer fields:  the array index of
  341.     the record, and the index of the next record in the free list
  342.     (which is used only if the record is not in use).  There's a
  343.     global called FREE that holds the index of the first free record.
  344.     
  345.     When I open a window, I pass the address of the first free record
  346.     for the “wStorage” argument of GetNewWindow.  Then I set FREE to
  347.     point to the next free record.  The last record points to -1, so
  348.     when all the records are in use, FREE = -1, and I put up an alert.
  349.     (This is a lot easier to code than to explain...)
  350.     
  351. *******************************************************************)
  352.  
  353.     procedure donew;
  354.         
  355.         label
  356.             100;
  357.     
  358.         var
  359.             dummy                :    integer;
  360.             windowtype        :    integer;
  361.             thewindow        :    WindowPtr;
  362.             thestring        :    Str255;
  363.     
  364.         begin
  365.             
  366.             if FREE < 0 then begin
  367.                 InitCursor;
  368.                 centerdialog('ALRT', messagedialog);
  369.                 dummy := Alert(messagedialog, nil);
  370.                 goto 100;
  371.             end;
  372.             
  373.             if OLDROM then
  374.                 windowtype := windownum
  375.             else
  376.                 windowtype := zoomwindnum;
  377.             
  378.             thewindow := GetNewWindow(windowtype,
  379.                             @WINDOWS[FREE], WindowPtr(-1));
  380.             placewindow(thewindow);
  381.             
  382.             WINDOWCOUNT := WINDOWCOUNT + 1;
  383.             NumToString(WINDOWCOUNT, thestring);
  384.             SetWTitle(thewindow,
  385.                             concat('Window Without a Title #', thestring));
  386.             
  387.             ShowWindow(thewindow);
  388.             
  389.             CalcMenuSize(WINDOWMENU);
  390.             
  391.             FREE := WINDOWS[FREE].next;
  392.             
  393. 100:    end;
  394.         
  395. (*******************************************************************
  396.     
  397.     doclose
  398.     -------
  399.     
  400.     Here I close a window; if it is an application window, it is
  401.     automatically deleted from the menu but the menu dimensions must
  402.     be recalculated.
  403.     
  404.     Now I must return the WindowRecord to the free list.  FREE
  405.     points to the first free record; I just set the newly-freed
  406.     record to point to that record, and set FREE to point to the
  407.     N.F.R. (newly-freed record).
  408.     
  409.     I just put in that array-of-WindowRecord, free-list stuff this
  410.     very morning, and I'm really taken with it.  Gonna have to
  411.     re-write all my old stuff...
  412.     
  413. *******************************************************************)
  414.  
  415.     procedure doclose(thepeek : WindowPeek);
  416.     
  417.         begin
  418.             
  419.             if thepeek^.windowkind < 0 then
  420.                 CloseDeskAcc(thepeek^.windowkind)
  421.             else begin
  422.                 CloseWindow(WindowPtr(thepeek));
  423.                 with datapointer(thepeek)^ do begin
  424.                     next := FREE;
  425.                     FREE := recordid;
  426.                 end;
  427.                 CalcMenuSize(WINDOWMENU);
  428.             end;
  429.             
  430.         end;
  431.         
  432. (******************************************************************)
  433.     
  434.     procedure doquit;
  435.         
  436.         var
  437.             thelong            :    longpointer;
  438.             thepeek            :    WindowPeek;
  439.         
  440.         begin
  441.             
  442.             thelong := longpointer(windowlist);
  443.             thepeek := WindowPeek(thelong^);
  444.             
  445.             while thepeek <> nil do begin
  446.                 doclose(thepeek);
  447.                 thepeek := thepeek^.nextwindow;
  448.             end;
  449.             
  450.             DONE := true;
  451.         
  452.         end;
  453.         
  454. (******************************************************************)
  455.  
  456.     procedure clickfilemenu(theitem : integer);
  457.     
  458.         begin
  459.             
  460.             case theitem of
  461.                 newitem            :    donew;
  462.                 closeitem        :    doclose(WindowPeek(FrontWindow));
  463.                 quititem            :    doquit;
  464.             end;
  465.             
  466.         end;
  467.         
  468. (*******************************************************************
  469.     
  470.     zoomthewindow
  471.     -------------
  472.     
  473.     This routine zooms the window.  If the refcon is zero, then the
  474.     window is in an unzoomed condition and should be zoomed out.
  475.     Otherwise, the window is at full screen and should be zoomed in.
  476.     
  477. *******************************************************************)
  478.     
  479.     procedure zoomthewindow(thewindow : WindowPtr);
  480.     
  481.         begin
  482.             
  483.             if GetWRefCon(thewindow) = 0 then begin
  484.                 ZoomWindow(thewindow, inZoomOut, true);
  485.                 SetWRefCon(thewindow, 1);
  486.             end else begin
  487.                 ZoomWindow(thewindow, inZoomIn, true);
  488.                 SetWRefCon(thewindow, 0);
  489.             end;
  490.             
  491.         end;
  492.         
  493. (*******************************************************************
  494.     
  495.     clickwindowmenu
  496.     ---------------
  497.     
  498.     If the “Zoom Front Window” command is selected, then call
  499.     “zoomthewindow” to do the zooming and update the refcon.
  500.     Otherwise, walk the window list to find the window desired and
  501.     select it.  This won't be the nth window but rather the nth
  502.     application window.
  503.     
  504. *******************************************************************)
  505.  
  506.     procedure clickwindowmenu(theitem : integer);
  507.     
  508.         var
  509.             thewindow        :    WindowPeek;
  510.             
  511.         begin
  512.             
  513.             if theitem = 1 then
  514.                 zoomthewindow(FrontWindow)
  515.             else if theitem > 2 then begin
  516.                 
  517.                 theitem := theitem - 2;
  518.                 
  519.                 thewindow := WindowPeek(longpointer(windowlist)^);
  520.                 while (not thewindow^.visible)
  521.                                 or (thewindow^.windowkind <> userKind) do
  522.                     thewindow := thewindow^.nextwindow;
  523.                 
  524.                 while theitem > 1 do begin
  525.                     theitem := theitem - 1;
  526.                     repeat
  527.                         thewindow := thewindow^.nextwindow;
  528.                     until thewindow^.visible
  529.                                     and (thewindow^.windowkind = userKind);
  530.                 end;
  531.                 
  532.                 SelectWindow(WindowPtr(thewindow));
  533.             
  534.             end;
  535.             
  536.         end;
  537.         
  538. (*******************************************************************
  539.     
  540.     checkmenu
  541.     ---------
  542.     
  543.     This routine is called just before MenuSelect or MenuKey, to
  544.     make sure the menu items are appropriately enabled or disabled.
  545.     Note that the “Zoom Front Window” item on the Window menu is
  546.     never enabled on the 64K ROM.
  547.     
  548. *******************************************************************)
  549.  
  550.     procedure checkmenu(thewindow : WindowPeek);
  551.     
  552.         begin
  553.             
  554.             DisableItem(EDITMENU, 0);
  555.             DisableItem(WINDOWMENU, zoomitem);
  556.             
  557.             if thewindow = nil then
  558.                 DisableItem(FILEMENU, closeitem)
  559.             else begin
  560.                 if thewindow^.windowkind <> userKind then
  561.                     EnableItem(EDITMENU, 0)
  562.                 else if not OLDROM then
  563.                     EnableItem(WINDOWMENU, zoomitem);
  564.                 EnableItem(FILEMENU, closeitem);
  565.             end;
  566.             
  567.         end;
  568.         
  569. (******************************************************************)
  570.  
  571.     procedure clickinmenu;
  572.             
  573.         var
  574.             choice            :    long;
  575.             
  576.         begin
  577.             
  578.             checkmenu(WindowPeek(FrontWindow));
  579.             choice := MenuSelect(MAINEVENT.where);
  580.             
  581.             case HiWord(choice) of
  582.                 applenum        :    clickapplemenu(LoWord(choice));
  583.                 filenum        :    clickfilemenu(LoWord(choice));
  584.                 editnum        :    if SystemEdit(LoWord(choice) - 1) then;
  585.                 windnum        :    clickwindowmenu(LoWord(choice));
  586.             end;
  587.  
  588.             HiliteMenu(0);
  589.         
  590.         end;
  591.         
  592. (*******************************************************************
  593.     
  594.     clickindrag
  595.     -----------
  596.     
  597.     A drag will take the window out of full-zoom position if it was
  598.     in it, so clear the refcon.
  599.     
  600. *******************************************************************)
  601.     
  602.     procedure clickindrag(thewindow : WindowPtr);
  603.         
  604.         begin
  605.             
  606.             DragWindow(thewindow, MAINEVENT.where, DRAGRECT);
  607.             SetWRefCon(thewindow, 0);
  608.  
  609.         end;
  610.         
  611. (*******************************************************************
  612.     
  613.     clickingrow
  614.     -----------
  615.     
  616.     Growing the window will take it out of full-zoom position if it
  617.     was in it, so clear the refcon afterwards.
  618.     
  619. *******************************************************************)
  620.     
  621.     procedure clickingrow(thewindow : WindowPtr);
  622.         
  623.         var
  624.             newsize            :    long;
  625.     
  626.         begin
  627.             
  628.             newsize := GrowWindow(thewindow, MAINEVENT.where, GROWRECT);
  629.             if newsize <> 0 then begin
  630.                 InvalRect(thewindow^.portRect);
  631.                 SizeWindow(thewindow, LoWord(newsize), HiWord(newsize), true);
  632.                 SetWRefCon(thewindow, 0);
  633.             end;
  634.  
  635.         end;
  636.         
  637. (******************************************************************)
  638.     
  639.     procedure clickingoaway(thewindow : WindowPtr);
  640.     
  641.         begin
  642.             
  643.             if TrackGoAway(thewindow, MAINEVENT.where) then
  644.                 doclose(WindowPeek(thewindow));
  645.  
  646.         end;
  647.         
  648. (*******************************************************************
  649.     
  650.     clickinzoom
  651.     -----------
  652.     
  653.     Instead of calling ZoomWindow directly, I'm going to call an
  654.     intermediate routine (discussed above) to keep track of whether
  655.     the window is zoomed in or out.
  656.     
  657. *******************************************************************)
  658.     
  659.     procedure clickinzoom(thewindow : WindowPtr; thezoom : integer);
  660.         
  661.         begin
  662.         
  663.             if TrackBox(thewindow, MAINEVENT.where, thezoom) then
  664.                 zoomthewindow(thewindow);
  665.             
  666.         end;
  667.         
  668. (******************************************************************)
  669.     
  670.     procedure aclick;
  671.         
  672.         var
  673.             location            :    integer;
  674.             thewindow        :    WindowPtr;
  675.             
  676.         begin
  677.             
  678.             location := FindWindow(MAINEVENT.where, thewindow);
  679.  
  680.             case location of
  681.                 inDesk        :    SysBeep(1);
  682.                 inMenuBar    :    clickinmenu;
  683.                 inSysWindow    :    SystemClick(MAINEVENT, thewindow);
  684.                 inContent    :    SelectWindow(thewindow);
  685.                 inDrag        :    clickindrag(thewindow);
  686.                 inGrow        :    clickingrow(thewindow);
  687.                 inGoAway        :    clickingoaway(thewindow);
  688.                 inZoomIn        :    clickinzoom(thewindow, inZoomIn);
  689.                 inZoomOut    :    clickinzoom(thewindow, inZoomOut);
  690.             end;
  691.         
  692.         end;
  693.         
  694. (******************************************************************)
  695.     
  696.     procedure akey;
  697.         
  698.         var
  699.             charcode            :    integer;
  700.             choice            :    long;
  701.     
  702.         begin
  703.             
  704.             if BitAnd(MAINEVENT.modifiers, cmdKey) <> 0 then begin
  705.     
  706.                 charcode := BitAnd(MAINEVENT.message, charCodeMask);
  707.                 checkmenu(WindowPeek(FrontWindow));
  708.                 choice := MenuKey(chr(charcode));
  709.                 
  710.                 if choice <> 0 then begin
  711.                 
  712.                     case HiWord(choice) of
  713.                         applenum        :    clickapplemenu(LoWord(choice));
  714.                         filenum        :    clickfilemenu(LoWord(choice));
  715.                         editnum        :    if SystemEdit(LoWord(choice) - 1) then;
  716.                         windnum        :    clickwindowmenu(LoWord(choice));
  717.                     end;
  718.                     
  719.                     HiliteMenu(0);
  720.                     
  721.                 end;
  722.                 
  723.             end;
  724.  
  725.         end;
  726.         
  727. (******************************************************************)
  728.     
  729.     procedure anactivate(thewindow : WindowPtr);
  730.         
  731.         var
  732.             savedport        :    GrafPtr;
  733.     
  734.         begin
  735.             
  736.             SetPort(thewindow);
  737.             DrawGrowIcon(thewindow);
  738.  
  739.         end;
  740.         
  741. (******************************************************************)
  742.     
  743.     procedure anupdate(thewindow : WindowPtr);
  744.         
  745.         var
  746.             savedport        :    GrafPtr;
  747.     
  748.         begin
  749.             
  750.             GetPort(savedport);
  751.             SetPort(thewindow);
  752.             
  753.             BeginUpdate(thewindow);
  754.                 
  755.                 ClipRect(thewindow^.portRect);
  756.                 EraseRect(thewindow^.portRect);
  757.                 DrawGrowIcon(thewindow);
  758.             
  759.             EndUpdate(thewindow);
  760.             
  761.             SetPort(savedport);
  762.  
  763.         end;
  764.         
  765. (******************************************************************)
  766.     
  767.     procedure mainloop;
  768.         
  769.         var
  770.             dummy                :    logical;
  771.     
  772.         begin
  773.             
  774.             repeat
  775.                 
  776.                 if JEVENT then
  777.                     dummy := waitnextevent(everyEvent, MAINEVENT,
  778.                                     GetCaretTime, nil)
  779.                 else begin
  780.                     SystemTask;
  781.                     dummy := GetNextEvent(everyEvent, MAINEVENT);
  782.                 end;
  783.                 
  784.                 if dummy then begin
  785.                     case MAINEVENT.what of
  786.                         mouseDown        :    aclick;
  787.                         keyDown            :    akey;
  788.                         activateEvt        :    anactivate(WindowPtr(MAINEVENT.message));
  789.                         updateEvt        :    anupdate(WindowPtr(MAINEVENT.message));
  790.                     end;
  791.                 end;
  792.             
  793.             until DONE;
  794.  
  795.         end;
  796.         
  797. (******************************************************************)
  798.     
  799.     begin
  800.         
  801.         initmac;
  802.         setupmenus;
  803.         initglobals;
  804.         
  805.         mainloop;
  806.         
  807.     end.
  808.         
  809. (******************************************************************)
  810.